<template>
  <div>

      <div class="logo-box clearfix">
        
          <img
            src="../../assets/image/logo1.png"
            class="main-logo"
            width="220"
            alt="Awesome Image"
          />
        

      </div>
      <div class="chart-box" >
        <el-card class="box-card" style="flex: 1 1 0%;">
          <div slot="header" style="height:40px">
            <div style="display: flex;">
              <div>
                <el-radio-group v-model="codeType">
                  <el-radio-button label="代码"></el-radio-button>
                  <el-radio-button label="属性"></el-radio-button>

                </el-radio-group>
                <span @click="collect()" v-if="!closeFlag">
                  <i :class="[isStar==true?'el-icon-star-on':'el-icon-star-off']" style="font-size:22px;color:#ffe156;margin-left:10px"></i>
                </span>
              </div>
              <div style="text-align: right; flex: 1 1 0%;position:relative">
                <!-- <el-input v-model="chartName" placeholder="请输入名称" style="width: 150px;height: 28px;margin-right: 10px;"></el-input> -->
                <i class="el-icon-question" @click="openTip()"></i>
                <el-button size="mini" @click="format()">格式化</el-button>
                <el-button size="mini" @click="links()">外部脚本</el-button>
                <el-button size="mini" @click="runCode()">运行</el-button>
                <el-button size="mini" @click="createChart()" v-if="closeFlag || createFlag">{{buttonType}}</el-button>

                <div class="tip" style="" v-if="tip">
                  <div>无需声明option变量，直接对option赋值</div>
                  <div>option={} √ </div>
                  <div>var option={} ×</div>
                  <div>
                    必须将echarts图表中option内容放置在option变量中，不可自定义变量名。
                  </div>
                  <div>
                    无需手动创建echart执行代码 myChart.setOption(option, true);  ×
                  </div>
                  
                </div>
              </div>
            </div>
          </div>
          <div style="height: 100%; width: 100%;overflow-y:auto">
            <editor
              style="height: 100%; width: 100%;"
              v-model="code"
              @init="editorInit"
              @input='codeChange'
              lang="javascript"
              :options="editorOptions"
              theme="chrome"
              ref="aceEditor"
              v-show="codeType=='代码'"
            ></editor>
            <JsonView :data="option" v-show="codeType=='属性'"></JsonView>
          </div>

        </el-card>
        <div style="width: 20px; height: 20px;"></div>
        <el-card class="box-card" style="flex: 1 1 0%;">
          <div slot="header" style="height:40px;display:flex">
            <div style="text-align: left;line-height: 30px;">
              版本：4.7.0
            </div>
            <div style="text-align: right; flex: 1 1 0%;">
              <el-switch
                style="margin-right:10px"
                v-model="theme"
                active-text="深色模式"
                inactive-text=""
                @change="runCode()">
              </el-switch>
              <el-button size="mini" icon="el-icon-download" @click="download">下载示例</el-button>
              <el-button size="mini" icon="el-icon-camera" @click="capture">截图</el-button>
            </div>
          </div>
          <div style="height:100%" id="chart" ref="customCanvas">
          
          </div>
        </el-card>
      </div>

    <!-- 创建图表 -->
    <el-dialog title="创建图表" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="图表名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入图表名称" />
        </el-form-item>
        
        <el-form-item label="所属图表"  prop="graph">
          <el-select v-model="form.graph" placeholder="请选择所属图表" clearable>
            <el-option
              v-for="dict in graphOptions"
              :key="dict.dictValue"
              :label="dict.dictLabel"
              :value="dict.dictValue"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="所属组件"  prop="component">
          <el-select v-model="form.component" placeholder="请选择所属组件" clearable>
            <el-option
              v-for="dict in componentOptions"
              :key="dict.dictValue"
              :label="dict.dictLabel"
              :value="dict.dictValue"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="图表介绍" prop="description">
          <el-input v-model="form.description" type="textarea" placeholder="请输入内容" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <el-dialog title="外部脚本" :visible.sync="linksOpen" width="500px" append-to-body>
      <div class="links">
      
        <el-tag
          :key="tag"
          v-for="tag in dynamicTags"
          :closable="closeFlag"
          :disable-transitions="false"
          @close="handleClose(tag)">
          {{tag}}
        </el-tag>
        <el-input
          class="input-new-tag"
          v-if="inputVisible"
          v-model="inputValue"
          ref="saveTagInput"
          size="small"
          @keyup.enter.native="handleInputConfirm"
          @blur="handleInputConfirm"
        >
        </el-input>
        <el-button v-else class="button-new-tag" size="small" @click="showInput" v-show="closeFlag || createFlag">添加脚本</el-button>
      </div>
      <div slot="footer" class="dialog-footer" v-if="closeFlag || createFlag">
        <el-button type="primary" @click="addLink()">确 定</el-button>
        <el-button @click="cancelLink()">取 消</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import JsonView from 'vue-json-views'
import Editor from 'vue2-ace-editor';
import html2canvas from 'html2canvas';
import { addGallery,updateGallery,getGallery,starIncrease,starDecrease } from "@/api/tool/datav/echartsGallery";
import { addEcharts,listEcharts,delUserEcharts } from "@/api/tool/datav/userEcharts";
import { download } from './js/download'
import {js_beautify} from './js/beautify.js'

import echarts from "echarts";
require("echarts/theme/macarons"); 
require("echarts/theme/dark"); // echarts theme
import resize from '@/views/dashboard/mixins/resize'

import 'echarts-gl'
import 'echarts-liquidfill'
import 'echarts-wordcloud'

import 'echarts/map/js/china'
import 'echarts/map/js/world'
import 'echarts/map/js/province/anhui'
import 'echarts/map/js/province/aomen'
import 'echarts/map/js/province/hebei'
import 'echarts/map/js/province/heilongjiang'
import 'echarts/map/js/province/henan'
import 'echarts/map/js/province/hubei'
import 'echarts/map/js/province/hunan'
import 'echarts/map/js/province/jiangsu'
import 'echarts/map/js/province/jiangxi'
import 'echarts/map/js/province/jilin'
import 'echarts/map/js/province/liaoning'
import 'echarts/map/js/province/neimenggu'
import 'echarts/map/js/province/beijing'
import 'echarts/map/js/province/ningxia'
import 'echarts/map/js/province/qinghai'
import 'echarts/map/js/province/shandong'
import 'echarts/map/js/province/shanghai'
import 'echarts/map/js/province/shanxi'
import 'echarts/map/js/province/shanxi1'
import 'echarts/map/js/province/sichuan'
import 'echarts/map/js/province/taiwan'
import 'echarts/map/js/province/tianjin'
import 'echarts/map/js/province/xianggang'
import 'echarts/map/js/province/chongqing'
import 'echarts/map/js/province/xinjiang'
import 'echarts/map/js/province/xizang'
import 'echarts/map/js/province/yunnan'
import 'echarts/map/js/province/zhejiang'
import 'echarts/map/js/province/fujian'
import 'echarts/map/js/province/gansu'
import 'echarts/map/js/province/guangdong'
import 'echarts/map/js/province/guangxi'
import 'echarts/map/js/province/guizhou'
import 'echarts/map/js/province/hainan'

export default {
   components: { 
    html2canvas,
    Editor,
    JsonView
  },
  data() {
    let checkGraph = (rule, value, callback) => {
      
        if((value == undefined || value == "") &&(this.form.component == undefined || this.form.component == "") ) {
          callback(new Error('图表与组件至少选择一个'));
        } else {
          callback();
        }
    };
    let checkComponent = (rule, value, callback) => {
      
        if((value == undefined || value == "") &&(this.form.graph == undefined || this.form.graph == "") ) {
          callback(new Error('图表与组件至少选择一个'));
        } else {
          callback();
        }
    };
    return {
      codeType: "代码",
      chartName: "",
      chart: null,
      code: '', //编辑器运行代码
      editorOptions: {
        // 设置代码编辑器的样式
        enableBasicAutocompletion: true, //启用基本自动完成
        enableSnippets: true, // 启用代码段
        enableLiveAutocompletion: true, //启用实时自动完成
        tabSize: 2, //标签大小
        fontSize: 18, //设置字号
        showPrintMargin: false, //去除编辑器里的竖线
      },
      screenHeight: document.body.clientHeight,
      screenWidth: document.body.clientWidth,
      open: false,//创建图表弹出框
      // 所属图表字典
      graphOptions: [],
      // 所属组件字典
      componentOptions: [],
      // 表单参数
      form: {},
      // 表单校验
      rules: {
        name: [
          { required: true, message: "图表名称不能为空", trigger: "blur" }
        ],
        graph: [
          { required: true, validator:checkGraph, trigger: "blur" }
        ],
        component: [
          { required: true, validator:checkComponent, trigger: "blur" }
        ],       
      },
      option: {}, //echarts option属性内容
      theme: false,//主题模式
      linksOpen: false,
      dynamicTags: [],
      inputVisible: false,
      inputValue: '',
      closeFlag: false,//标签是否可关闭
      isStar: false,//是否收藏标志
      createFlag:false,
      buttonType:"创建",//创建按钮
      tip:false,//提示框
    }
  },
  watch: {
    screenWidth: {
      handler: function (val) {
        if (this.chart != null) {
          this.chart.resize();
        }
      },
      // immediate: true,
      deep: true,
    },
    screenHeight: {
      handler: function (val) {
        if (this.chart != null) {
          this.chart.resize();
        }
      },
      // immediate: true,
      deep: true,
    },
  },
  mounted() {
    window.onresize = () => {
      return (() => {
        this.screenWidth = document.body.clientWidth;
        this.screenHeight = document.body.clientHeight;
      })();
    };

    let id =  this.$route.query.id;
    if(id != undefined){
      getGallery(Number(id)).then(response => {
        
        new Promise((res,rej) => {
          this.form = response.data;
          
          if(response.data.createBy == this.$store.getters.name){
            this.closeFlag = true;
            this.buttonType = "编辑"
          }

          if(this.form.links != null){
            this.dynamicTags = this.form.links.split(",")
              this.dynamicTags.forEach(element => {
                
                let script = document.createElement('script');
                script.type = 'text/javascript';
                script.src = element;
                document.body.appendChild(script);
              });
              
          }
        }).then(
          this.code = response.data.chartOption
        )

       
      });
    }else{
      this.createFlag = true
    }

    let query = {chartId:this.$route.query.id,username:this.$store.getters.name}
    listEcharts(query).then(response => {
      if(response.code == 200){
        //收藏
        if(response.total > 0){
          this.isStar = true;
        }
        //未收藏
        else{
          this.isStar = false;
        }
      }
    })


  },
  created() {
    this.getDicts("datav_graph").then(response => {
      this.graphOptions = response.data;
    });
    this.getDicts("datav_component").then(response => {
      this.componentOptions = response.data;
    });

  },
  methods: {
    codeChange(val){
      if(val != ""){

        this.runCode()
      }
    },
    editorInit(editor) {
      require('brace/ext/searchbox') //添加搜索功能
      require('brace/theme/chrome');
      require('brace/ext/language_tools'); //language extension prerequsite...
      require('brace/mode/yaml');
      require('brace/mode/json');
      require('brace/mode/less');
      require('brace/snippets/json');
      require('brace/mode/lua');
      require('brace/snippets/lua');
      require('brace/mode/javascript');
      require('brace/snippets/javascript');
      //自动换行
      editor.setOption("wrap", "free")
    },
    runCode(){
      if(this.chart != null){
        this.chart.dispose();
        this.chart = null;
      }
      let themeColor = 'macarons'
      if(this.theme){
        themeColor = 'dark'
      }

      this.chart = echarts.init(document.getElementById('chart'), themeColor);
      
      let chartOption = this.evalCode();
      
      //echarts option属性
      if(chartOption){

        this.option = chartOption;
      }
    },
    format(){
      let aceEditor = this.$refs.aceEditor;
      let val = aceEditor.editor.session.getValue();
      //格式化
      var jsbOpts = { 
 
          indent_size : 4
      
      }; 
      aceEditor.editor.session.setValue(js_beautify(val, jsbOpts))
    },
    createChart(){
      let chartOption = this.evalCode();

      if(chartOption){
        this.open = true
      }else{
        this.msgError("代码编译不通过，请查看代码后在保存");
      }
    },
    evalCode(){
      let that = this;
      let chartCode = JSON.parse(JSON.stringify( this.code ));
      return (function(echarts, myChart, requestParameters){
        //里面为要处理的代码块
        try{
          let option;
          eval(chartCode)
          if(option) {
            // console.log("option:",option);
            that.chart.setOption(option, true);
            return option;
          }
        }catch(e){
          console.log("--err-",e) 
        }
        
      })(echarts, this.chart, "你所传的参数")
    },
    submitForm(){
      this.$refs["form"].validate(valid => {
        if (valid) {

          this.form.chartOption = this.code;
          html2canvas(this.$refs.customCanvas, {
              backgroundColor: null,
      　　　　 useCORS: true // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
          }).then((canvas) => {
            let url = canvas.toDataURL('image/png')
            //console.log(url);
            this.form.thumbnail = url;
            if (this.form.id != undefined) {
              updateGallery(this.form).then(response => {
                if (response.code === 200) {
                  this.msgSuccess("创建成功");
                  this.open = false;
                  window.open("/cms/community",'_self')
                } else {
                  this.msgError(response.msg);
                }
              });
            } else {
              addGallery(this.form).then(response => {
                if (response.code === 200) {
                  this.msgSuccess("创建成功");
                  this.open = false;
                  window.open("/cms/community",'_self')
                } else {
                  this.msgError(response.msg);
                }
              });
            }
          })
        }
      });          

    },
    cancel() {
      this.open = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.form = {
        name: undefined,
        chartOption: undefined,
        graph: undefined,
        component: undefined,
        thumbnail: undefined,
      };
      this.resetForm("form");
    },
    //截图
    capture(){
      let that = this;
      let a = document.createElement('a');
      html2canvas(this.$refs.customCanvas, {
        backgroundColor: null,
　　　　   useCORS: true // 如果截图的内容里有图片,可能会有跨域的情况,加上这个参数,解决文件跨域问题
      }).then((canvas) => {
        let dom = document.body.appendChild(canvas);
        a.style.display = 'none';
        document.body.removeChild(dom);
        let blob = that.dataURLToBlob(dom.toDataURL('image/png'));
        a.setAttribute('href', URL.createObjectURL(blob));
        //这块是保存图片操作  可以设置保存的图片的信息
        let pname = String(Math.random()).replace(".", "");
        a.setAttribute('download', pname + '.png');
        document.body.appendChild(a);
        a.click();
        URL.revokeObjectURL(blob);
        document.body.removeChild(a);
      })
    },
    //图片格式转换方法
    dataURLToBlob(dataurl) {
        let arr = dataurl.split(',');
        let mime = arr[0].match(/:(.*?);/)[1];
        let bstr = atob(arr[1]);
        let n = bstr.length;
        let u8arr = new Uint8Array(n);
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], { type: mime });
    },
    download(){
        download(this.option,this.dynamicTags)
    },
    collect(){
      let data = {chartId:this.$route.query.id,username:this.$store.getters.name}
      if(!this.isStar){

        addEcharts(data).then(response => {
          if (response.code === 200) {
            // tarIncrease,starDecrease
            let starData = {id: this.$route.query.id}
            starIncrease(starData).then(res =>{
              if(res.code == 200){
                this.msgSuccess("收藏成功");
                this.isStar = true;
              }
              else {
                this.msgError(res.msg);
              }
            })
          } else {
            this.msgError(response.msg);
          }
        });
      }else{
        delUserEcharts(data).then(response => {
          if (response.code === 200) {
            let starData = {id: this.$route.query.id}
            starDecrease(starData).then(res =>{
              if(res.code = 200){
                this.msgSuccess("取消收藏");
                this.isStar = false;
              }
              else{
                this.msgError(res.msg)
              }
            })
          } else {
            this.msgError(response.msg);
          }
        });
      }
    },
    links(){
      this.linksOpen = true;
    },
    handleClose(tag) {
        this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
    },

    showInput() {
      this.inputVisible = true;
      this.$nextTick(_ => {
        this.$refs.saveTagInput.$refs.input.focus();
      });
    },

    handleInputConfirm() {
      let inputValue = this.inputValue;
      if (inputValue) {
        this.dynamicTags.push(inputValue);
      }
      this.inputVisible = false;
      this.inputValue = '';
    },
    addLink(){
      this.form.links = this.dynamicTags.join(",");
      this.linksOpen = false;
    },
    cancelLink(){
      this.linksOpen = false;
    },
    openTip(){
      this.tip = !this.tip;
    }
  },
}
</script>

<style scoped>
.logo-box{
  padding: 10px 20px;
}
.chart-box{
  display: flex;
  padding: 10px;
  position: absolute;
  top: 60px;
  width: 100%;
  height: calc(100% - 60px);
}
.tip{
  position: absolute;
  top:40px;
  left:320px;
  width:320px;
  height:auto;
  line-height: 24px;
  padding: 10px;
  z-index:99;
  background-color: #6c717514;
  text-align: left;
  font-family: "微软雅黑";
}
::v-deep .box-card .el-card__body {
  padding: 0px;
  height: calc(100% - 70px);
  width: 100%;
}

::v-deep .links .el-tag {
    background-color: #e8f4ff;
    border-color: #d1e9ff;
    color: #1890ff;
    display: inline-block;
    height: 32px;
    padding: 0 10px;
    line-height: 30px;
    font-size: 12px;
    color: #1890ff;
    border-width: 1px;
    border-style: solid;
    border-radius: 4px;
    box-sizing: border-box;
    white-space: nowrap;
    margin-top: 10px;
}
::v-deep .links .button-new-tag{
  margin-top: 10px;
}
::v-deep .links .input-new-tag{
  margin-top: 10px;
}

/**  滚动条凹槽的颜色，还可以设置边框属性  **/
::-webkit-scrollbar-track-piece { 

  background-color:#f8f8f8; 
  border-radius: 10px;
}
/** 滚动条的宽度  **/
::-webkit-scrollbar {

  width:9px;

  height:9px; 

}
/** 滚动条的设置  **/
::-webkit-scrollbar-thumb {

  background-color:#dddddd;

  background-clip:padding-box;

  min-height:28px; 
  border-radius: 10px;

}

::-webkit-scrollbar-thumb:hover {

  background-color:#bbb; 

}
</style>